#pragma once
#include <ctime>
#include <Windows.h>
#include <sstream>
std::time_t getTimeStamp(bool _13);

static std::stringstream stream;
template<class out_type, class in_type>
static out_type  convert(const in_type& t)
{
	stream.clear();
	stream.str("");
	stream << t;
	out_type result;
	stream >> result;

	return result;
}


namespace string_convert {
#define new_str(_name,_len,_type) std::shared_ptr<_type> ##_name(new _type[_len + 1]); RtlZeroMemory(##_name.get(), _len + 1);

	__forceinline std::wstring UTF8ToUnicode(const char* str) noexcept
	{
		auto len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
		new_str(result, len, wchar_t);
		MultiByteToWideChar(CP_UTF8, 0, str, -1, result.get(), len);
		return std::wstring(result.get());
	}

	__forceinline std::string UnicodeToUTF8(const wchar_t* str) noexcept
	{
		auto len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
		new_str(result, len, char);
		WideCharToMultiByte(CP_UTF8, 0, str, -1, result.get(), len, NULL, NULL);
		return std::string(result.get());
	}

	__forceinline std::wstring ANSIToUnicode(const char* str) noexcept
	{
		auto len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
		new_str(result, len, wchar_t);
		MultiByteToWideChar(CP_ACP, 0, str, -1, result.get(), len);
		return std::wstring(result.get());
	}

	__forceinline std::string UnicodeToANSI(const wchar_t* str) noexcept
	{
		auto len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
		new_str(result, len, char);
		WideCharToMultiByte(CP_ACP, 0, str, -1, result.get(), len, NULL, NULL);
		return std::string(result.get());
	}

	__forceinline std::string ANSIToUTF8(const char* str) noexcept
	{
		return UnicodeToUTF8(ANSIToUnicode(str).c_str());
	}

	__forceinline std::string UTF8ToANSI(const char* str) noexcept
	{
		return UnicodeToANSI(UTF8ToUnicode(str).c_str());
	}
}